package com.bestcem.xm.ticket.grpc.client;

import cn.hutool.core.lang.ObjectId;
import com.bestcem.bp.grpc.v1.base.Code;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.ticket.grpc.client.convert.TicketBaseUserConvert;
import com.bestcem.xm.ticket.grpc.client.dto.user.*;
import com.bestcem.xm.user.grpc.v1.enums.GroupStatusEnum;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.bestcem.bp.grpc.v1.base.Code.ERROR;

/**
 * 倍市得 user 模块相关rpc接口客户端
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version v1.0
 * @date 2021/6/21 16:26
 */
@Slf4j
@Service
public class TicketBaseUserGrpcService {

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserGroupServiceGrpc.UserGroupServiceBlockingStub userGroupServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private OrgServiceGrpc.OrgServiceBlockingStub orgServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserRoleServiceGrpc.UserRoleServiceBlockingStub userRoleServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private SmtpServiceGrpc.SmtpServiceBlockingStub smtpServiceBlockingStub;


    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/20 14:53
     */
    @Nullable
    public UserDTO getUser(String userId) {
        if (!ObjectId.isValid(userId)) {
            return null;
        }
        GetUserByIdRequest.Builder builder = GetUserByIdRequest.newBuilder();
        builder.setId(userId);
        try {
            GetUserByIdResponse response = userServiceBlockingStub.getUserById(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getUser {} Error; ErrorMsg: {}", userId, response);
                return null;
            }
            return TicketBaseUserConvert.toUserDTO(response.getUser());
        } catch (Exception e) {
            log.error("[Ticket] USER getUser {} Error", userId, e);
            return null;
        }
    }

    /**
     * 获取用户角色信息
     *
     * @param userId 用户id
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/11/4 20:30
     */
    @Nullable
    public List<UserRoleDTO> getUserRole(String userId) {
        ListUserRolesRequest.Builder builder = ListUserRolesRequest.newBuilder();
        builder.setUserId(userId);
        try {
            ListUserRolesResponse response = userServiceBlockingStub.listUserRoles(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getUserRole {} Error; ErrorMsg: {}", userId, response);
                return null;
            }
            return TicketBaseUserConvert.toUserRoleDTOList(response.getRolesList());
        } catch (Exception e) {
            log.error("[Ticket] USER getUserRole {} Error", userId, e);
            return null;
        }
    }

    /**
     * 根据id批量获取用户信息
     *
     * @param userIds 用户id
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/20 14:53
     */
    @Nullable
    public List<UserDTO> listUserByIds(Collection<String> userIds) {
        ListUsersByIdsRequest.Builder builder = ListUsersByIdsRequest.newBuilder();
        builder.addAllIds(userIds);
        try {
            ListUsersByIdsResponse response = userServiceBlockingStub.listUsersByIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listUserByIds {} Error; ErrorMsg: {}", userIds, response);
                return new ArrayList<>();
            }
            return TicketBaseUserConvert.toUserDTOList(response.getUsersList());
        } catch (Exception e) {
            log.error("[Ticket] USER listUserByIds {} Error", userIds, e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取单个Group
     *
     * @param groupId 成员组 id
     * @return com.bestcem.xm.ticket.grpc.client.dto.user.GroupDTO 成员组
     * @author <yuming.pan@idiaoyan.com>
     * @date 20:55 2021/8/26
     */
    @Nullable
    public GroupDTO getGroup(String groupId) {
        if (!ObjectId.isValid(groupId)) {
            return null;
        }
        GetGroupRequest.Builder builder = GetGroupRequest.newBuilder();
        builder.setId(groupId);
        try {
            GetGroupResponse response = userGroupServiceBlockingStub.getGroup(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getGroup {} Error; ErrorMsg: {}", groupId, response);
                return null;
            }
            return TicketBaseUserConvert.toGroupDTO(response.getGroup());
        } catch (Exception e) {
            log.error("[Ticket] USER getGroup {} Error; ErrorMsg: {}", groupId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过查询条件批量一次性获取所有符合条件的Group
     *
     * @param orgId 组织ID
     * @param code  组编码
     * @return 成员组DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 10:38 2021/8/27
     */
    @Nullable
    public List<GroupDTO> listGroupByOrgIdAndCode(String orgId, String code) {
        ListGroupsRequest.Builder builder = ListGroupsRequest.newBuilder();
        GroupCondition.Builder groupBuilder = GroupCondition.newBuilder();
        groupBuilder.setOrgId(orgId);
        groupBuilder.setCode(code);
        builder.setGroup(groupBuilder.build());
        // 过滤删除状态

        List<GroupStatusEnum.GroupStatus> status = new ArrayList<>();
        status.add(GroupStatusEnum.GroupStatus.ACTIVATED);
        status.add(GroupStatusEnum.GroupStatus.HIDDEN);
        builder.addAllStatuses(status);
        try {
            ListGroupsResponse response = userGroupServiceBlockingStub.listGroups(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listGroupByOrgIdAndCode {},{} Error; ErrorMsg: {}", orgId, code, response);
                return null;
            }
            return TicketBaseUserConvert.toGroupDTOList(response.getGroupsList());
        } catch (Exception e) {
            log.error("[Ticket] USER listGroupByOrgIdAndCode {},{} Error; ErrorMsg: {}", orgId, code, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取单个GroupLevel
     *
     * @param groupLevelId 成员组层级id
     * @return 成员组层级DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 11:22 2021/8/27
     */
    @Nullable
    public GroupLevelDTO getGroupLevel(String groupLevelId) {
        GetGroupLevelByIdRequest.Builder builder = GetGroupLevelByIdRequest.newBuilder();
        builder.setLevelId(groupLevelId);
        try {
            GetGroupLevelByIdResponse response = userGroupServiceBlockingStub.getGroupLevelById(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getGroupLevel {} Error; ErrorMsg: {}", groupLevelId, response);
                return null;
            }
            return TicketBaseUserConvert.toGroupLevelDTO(response.getLevel());
        } catch (Exception e) {
            log.error("[Ticket] USER getGroupLevel {} Error; ErrorMsg: {}", groupLevelId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取单个Organization
     *
     * @param organizationId 组织id
     * @return 组织DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 13:52 2021/8/27
     */
    @Nullable
    public OrganizationDTO getOrganization(String organizationId) {
        GetOrgByIdOrCodeRequest.Builder builder = GetOrgByIdOrCodeRequest.newBuilder();
        builder.setId(organizationId);
        try {
            GetOrgByIdOrCodeResponse response = orgServiceBlockingStub.getOrgByIdOrCode(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getOrganization {} Error; ErrorMsg: {}", organizationId, response);
                return null;
            }
            return TicketBaseUserConvert.toOrganizationDTO(response.getOrg());
        } catch (Exception e) {
            log.error("[Ticket] USER getOrganization {} Error; ErrorMsg: {}", organizationId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取单个Role
     *
     * @param roleId 角色id
     * @return 角色DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 14:51 2021/8/27
     */
    @Nullable
    public RoleDTO getRole(String roleId) {
        GetRoleRequest.Builder builder = GetRoleRequest.newBuilder();
        builder.setId(roleId);
        try {
            GetRoleResponse response = userRoleServiceBlockingStub.getRole(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getRole {} Error; ErrorMsg: {}", roleId, response);
                return null;
            }
            return TicketBaseUserConvert.toRoleDTO(response.getRole());
        } catch (Exception e) {
            log.error("[Ticket] USER getRole {} Error; ErrorMsg: {}", roleId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过查询条件批量一次性获取所有符合条件的Role
     *
     * @param orgId    组织ID
     * @param roleName 角色名
     * @return 角色DTO集合
     * @author <yuming.pan@idiaoyan.com>
     * @date 15:07 2021/8/27
     */
    @Nullable
    public List<RoleDTO> listRoleByOrgIdAndRoleName(String orgId, String roleName) {
        ListRolesRequest.Builder builder = ListRolesRequest.newBuilder();
        RoleCondition.Builder roleBuilder = RoleCondition.newBuilder();
        roleBuilder.setOrgId(orgId);
        roleBuilder.setName(roleName);
        builder.setRole(roleBuilder.build());
        try {
            ListRolesResponse response = userRoleServiceBlockingStub.listRoles(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listRoleByOrgIdAndRoleName {},{} Error; ErrorMsg: {}", orgId, roleName, response);
                return null;
            }
            return TicketBaseUserConvert.toRoleDTOList(response.getRolesList());
        } catch (Exception e) {
            log.error("[Ticket] USER listRoleByOrgIdAndRoleName {},{} Error; ErrorMsg: {}", orgId, roleName, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过查询条件批量一次性获取所有符合条件的Smtp
     *
     * @param orgId    组织id
     * @param isNotice 是否是默认内部通知邮箱
     * @return 邮箱设置DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 15:41 2021/8/27
     */
    @Nullable
    public List<SmtpDTO> listSmtpByOrgId(String orgId, boolean isNotice) {
        ListSmtpsRequest.Builder builder = ListSmtpsRequest.newBuilder();
        SmtpConditon.Builder smtpBuilder = SmtpConditon.newBuilder();
        smtpBuilder.setOrgId(orgId);
        smtpBuilder.setNotice(isNotice);
        builder.setSmtp(smtpBuilder.build());
        try {
            ListSmtpsResponse response = smtpServiceBlockingStub.listSmtps(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listSmtpByOrgId {},{} Error; ErrorMsg: {}", orgId, isNotice, response);
                return null;
            }
            return TicketBaseUserConvert.toSmtpDTOList(response.getSmtpsList());
        } catch (Exception e) {
            log.error("[Ticket] USER listSmtpByOrgId {},{} Error; ErrorMsg: {}", orgId, isNotice, e.getMessage(), e);
            return null;
        }
    }

    public SmtpDTO getSmtpById(String smtpId) {
        GetSmtpByIdRequest.Builder builder = GetSmtpByIdRequest.newBuilder();
        builder.setId(smtpId);
        try {
            GetSmtpByIdResponse response = smtpServiceBlockingStub.getSmtpById(builder.build());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[ticket] USER getSmtpById {} Error; ErrorMsg: {}", smtpId, response);
                return null;
            }
            return TicketBaseUserConvert.toSmtpDTO(response.getSmtp());
        } catch (Exception e) {
            log.error("[ticket] USER getSmtpById {} Error;", smtpId, e);
            return null;
        }
    }

    /**
     * 通过查询条件批量一次性获取所有符合条件的UserGroup
     *
     * @param groupId groupId
     * @return 用户和组的关联DTO
     * @author <yuming.pan@idiaoyan.com>
     * @date 16:41 2021/8/27
     */
    @Nullable
    public List<UserGroupDTO> listUserGroupByGroupId(String groupId) {
        int total, page = 1;
        List<UserGroupDTO> result = new ArrayList<>();
        if (!ObjectId.isValid(groupId)) {
            return result;
        }
        do {
            ListUserGroupsRequest.Builder builder = ListUserGroupsRequest.newBuilder();
            builder.setGroupId(groupId);
            Page.Builder pageBuilder = Page.newBuilder();
            pageBuilder.setPage(page);
            pageBuilder.setSize(1000);
            builder.setPage(pageBuilder.buildPartial());

            try {
                ListUserGroupsResponse response = userGroupServiceBlockingStub.listUserGroups(builder.buildPartial());
                if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                    log.error("[Ticket] USER listUserGroup {} Error; ErrorMsg: {}", groupId, response);
                    return null;
                }
                total = response.getTotal();
                List<UserGroupDTO> userGroupDTOS = TicketBaseUserConvert.toUserGroupDTOList(response.getGroupsList());
                if (CollectionUtils.isEmpty(userGroupDTOS)) {
                    break;
                }
                result.addAll(userGroupDTOS);
            } catch (Exception e) {
                log.error("[Ticket] USER listUserGroup {} Error; ErrorMsg: {}", groupId, e.getMessage(), e);
                return result;
            }
            page += 1;
        }
        while (result.size() < total);

        return result;
    }


}
